package com.iafme.listener;

import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.hutool.core.convert.Convert;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.alibaba.fastjson.JSON;
import com.systemframework.constants.Constants;
import com.systemframework.redis.RedisCache;
import com.systemframework.sys.dto.response.OnlineUserResponseDTO;
import com.systemframework.sys.entity.SysUser;
import com.systemframework.sys.service.SysUserService;
import com.systemframework.util.IpKit;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * @author summer
 * @version 1.0
 * @date 2024/10/23 17:05
 */
@Component
@Slf4j
@AllArgsConstructor
public class UserActionListener implements SaTokenListener {

    private final SaTokenConfig saTokenConfig;

    private final RedisCache redisCache;

    private final SysUserService sysUserService;

    /** 每次登录时触发 */
    @Override
    public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
        HttpServletRequest request = Convert.convert(ServletRequestAttributes.class, RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = IpKit.getRealIp(request);
        UserAgent userAgent = UserAgentUtil.parse(request.getHeader(Constants.USER_AGENT));
        Object userName = loginModel.getExtra(Constants.USER_NAME);
        SysUser sysUser = sysUserService.getById(Convert.convert(Integer.class, loginId));
        OnlineUserResponseDTO onlineUserResponseDTO = OnlineUserResponseDTO.builder()
                .osName(userAgent.getOs().getName())
                .id(sysUser.getId())
                .name(sysUser.getName())
                .loginTime(LocalDateTime.now())
                .browserName(userAgent.getBrowser().toString())
                .ip(ip)
                .username(Convert.convert(String.class, userName)).build();
        if(saTokenConfig.getTimeout()==-1){
            redisCache.set(Constants.ONLINE_USER+tokenValue, JSON.toJSONString(onlineUserResponseDTO));
        }else{
            redisCache.set(Constants.ONLINE_USER+tokenValue, JSON.toJSONString(onlineUserResponseDTO), saTokenConfig.getTimeout(), TimeUnit.SECONDS);
        }
        log.info("doLogin:{}",tokenValue);
    }

    /** 每次注销时触发 */
    @Override
    public void doLogout(String loginType, Object loginId, String tokenValue) {
        redisCache.delete(Constants.ONLINE_USER+tokenValue);
        log.info("doLogout:{}",tokenValue);
    }

    /** 每次被踢下线时触发 */
    @Override
    public void doKickout(String loginType, Object loginId, String tokenValue) {
        redisCache.delete(Constants.ONLINE_USER+tokenValue);
    }

    /** 每次被顶下线时触发 */
    @Override
    public void doReplaced(String loginType, Object loginId, String tokenValue) {
        redisCache.delete(Constants.ONLINE_USER+tokenValue);
    }

    /** 每次被封禁时触发 */
    @Override
    public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) {
        System.out.println("---------- 自定义侦听器实现 doDisable");
    }

    /** 每次被解封时触发 */
    @Override
    public void doUntieDisable(String loginType, Object loginId, String service) {
        System.out.println("---------- 自定义侦听器实现 doUntieDisable");
    }

    /** 每次二级认证时触发 */
    @Override
    public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) {
        System.out.println("---------- 自定义侦听器实现 doOpenSafe");
    }

    /** 每次退出二级认证时触发 */
    @Override
    public void doCloseSafe(String loginType, String tokenValue, String service) {
        System.out.println("---------- 自定义侦听器实现 doCloseSafe");
    }

    /** 每次创建Session时触发 */
    @Override
    public void doCreateSession(String id) {
        System.out.println("---------- 自定义侦听器实现 doCreateSession");
    }

    /** 每次注销Session时触发 */
    @Override
    public void doLogoutSession(String id) {
        System.out.println("---------- 自定义侦听器实现 doLogoutSession");
    }

    /** 每次Token续期时触发 */
    @Override
    public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
        System.out.println("---------- 自定义侦听器实现 doRenewTimeout");
    }
}
